﻿using DimensionsHelper.Common.Contracts.Metadata;
using Style = DimensionsHelper.Common.Contracts.Metadata.Style;

namespace DimensionsHelper.Client.WinUi.ViewModels;

public partial class MetadataCategoryViewModel(string name)
    : MetadataNamedViewModel(name, MetadataNamedObjectKind.Category)
{
    private readonly List<MetadataPropertyViewModel> _properties = [];
    private readonly List<MetadataTemplateViewModel> _templates = [];
    private MetadataStyleViewModel? _style;

    public IEnumerable<MetadataPropertyViewModel> Properties => _properties;

    public IEnumerable<MetadataTemplateViewModel> Templates => _templates;

    public MetadataStyleViewModel Style => _style ?? new MetadataStyleViewModel();

    public ElementType ElementType
    {
        get;
        private set;
    }


    public void SetStyle(MetadataStyleViewModel style)
    {
        _style = style;
        style.Parent = this;
    }


    public void AddProperty(MetadataPropertyViewModel property)
    {
        int index = _properties.FindIndex(p => p.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase));

        if (index >= 0)
        {
            _properties[index] = property;
        }
        else
        {
            _properties.Add(property);
        }

        property.Parent = this;
    }


    public void AddTemplate(MetadataTemplateViewModel template)
    {
        int index = _templates.FindIndex(t => t.Name.Equals(template.Name, StringComparison.OrdinalIgnoreCase));

        if (index >= 0)
        {
            _templates[index] = template;
        }
        else
        {
            _templates.Add(template);
        }

        template.Parent = this;
    }


    public static MetadataCategoryViewModel FromMetadata(int number) => new(number.ToString());


    public static MetadataCategoryViewModel FromMetadata(IElement element)
    {
        MetadataCategoryViewModel category = new(element.Name)
        {
            ElementType = element.ElementType
        };

        // properties
        foreach (IProperty property in element.Properties)
        {
            category.AddProperty(new MetadataPropertyViewModel(property.Name)
            {
                Value = property.Value
            });
        }

        // templates
        foreach (ITemplate template in element.Templates)
        {
            category.AddTemplate(new MetadataTemplateViewModel(template.Name)
            {
                Value = template.Value
            });
        }

        // style
        if (element.Style != null)
        {
            Style? current = element.Style.Get(element.Document.Context);
            if (current != null)
            {
                category.SetStyle(MetadataStyleViewModel.FromMetadata(current));
            }
        }

        // sub list
        if (element.Categories != null)
        {
            foreach (IElement e in element.Categories.GetElements())
            {
                category.AddChild(FromMetadata(e));
            }
        }

        return category;
    }
}